package com.timebank.volunteer.service.impl;

import com.timebank.common.core.constant.*;
import com.timebank.common.core.exception.volunteer.VolunteerException;
import com.timebank.common.core.result.Result;
import com.timebank.common.core.web.pojo.AjaxResult;
import com.timebank.common.security.utils.SecurityUtils;
import com.timebank.timecoin.pojo.entity.TimeCoinTrade;
import com.timebank.timecoin.pojo.vo.TimeCoinTradeVO;
import com.timebank.timecoin.service.RemoteTimeCoinService;
import com.timebank.volunteer.mapper.VolunteerAttendListMapper;
import com.timebank.volunteer.mapper.VolunteerListMapper;
import com.timebank.volunteer.mapper.VolunteerSignListMapper;
import com.timebank.volunteer.mapper.VolunteerMapper;
import com.timebank.volunteer.pojo.entity.Volunteer;
import com.timebank.volunteer.pojo.entity.VolunteerAttendList;
import com.timebank.volunteer.pojo.entity.VolunteerList;
import com.timebank.volunteer.pojo.entity.VolunteerSignList;
import com.timebank.volunteer.pojo.vo.VolunteerAttendListVO;
import com.timebank.volunteer.pojo.vo.VolunteerSignListVO;
import com.timebank.volunteer.pojo.vo.VolunteerVO;
import com.timebank.volunteer.service.VolunteerSignListService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 志愿服务 签到名单 实现类
 * @author shiliuyinzhen
 */
@Service
public class VolunteerSignListServiceImpl implements VolunteerSignListService {

    @Resource
    private VolunteerSignListMapper volunteerSignListMapper;

    @Resource
    private VolunteerMapper volunteerMapper;

    @Resource
    private VolunteerListMapper volunteerListMapper;

    @Resource
    private VolunteerAttendListMapper volunteerAttendListMapper;

    @Resource
    private RemoteTimeCoinService remoteTimeCoinService;

    /**
     * 根据志愿服务id获取签到名单
     * @param volunteerId
     * @return
     */
    @Override
    public List<VolunteerSignListVO> getSignListByVolunteerId(Long volunteerId) {
        //校验用户权限
        checkUserPermission(volunteerId);
        VolunteerSignList volunteerSignList = new VolunteerSignList();
        volunteerSignList.setVolunteerId(volunteerId);
        return volunteerSignListMapper.getSignList(volunteerSignList);
    }

    /**
     * 校验用户权限
     * @param volunteerId
     */
    private void checkUserPermission(Long volunteerId) {
        //查询志愿服务
        Volunteer volunteer = volunteerMapper.getVolunteerById(volunteerId);
        if (volunteer == null){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_NOT_FOUND +",id: " + volunteerId);
        }
        Long userId = SecurityUtils.getUserId();
        //如果该用户不是管理员，也不是志愿服务的发布人
        if (!SecurityUtils.isAdmin(userId) && volunteer.getPublisherId() != userId){
            //没有相关权限
            throw new VolunteerException(VolunteerExceptionConstant.USER_NOT_HAVE_PERMISSION);
        }
    }

    /**
     * 志愿者签到
     * @param volunteerId
     * @return
     */
    @Override
    @Transactional
    public AjaxResult insertSignList(Long volunteerId) {
        //查询志愿服务
        Volunteer volunteer = volunteerMapper.getVolunteerById(volunteerId);
        if (volunteer == null){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_NOT_FOUND +",id: " + volunteerId);
        }
        //如果签到没有开启
        if (volunteer.getSignStatus() == VolunteerSignStatusConstant.SIGN_DISABLE){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_SIGN_DISABLE);
        }
        LocalDateTime currentTime = LocalDateTime.now();
        LocalDateTime signBeginTime = volunteer.getSignBeginTime();
        LocalDateTime signEndTime = volunteer.getSignEndTime();
        //如果签到还未开始
        if (signBeginTime.isAfter(currentTime)){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_SIGN_NOT_BEGIN);
        }
        //如果签到已经结束
        if (signEndTime.isBefore(currentTime)){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_SIGN_HAS_ENDED);
        }
        //查询志愿服雾参与列表
        VolunteerList volunteerList = new VolunteerList();
        volunteerList.setVolunteerId(volunteerId);
        volunteerList.setUserId(SecurityUtils.getUserId());
        VolunteerList volunteerList2 = volunteerListMapper.getVolunteerList(volunteerList);
        //如果没找到数据
        if (volunteerList2 == null){
            //未报名志愿服务
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_NOT_SIGN_UP);
        }
        //查找签到名单
        VolunteerSignList volunteerSignList = VolunteerSignList.builder()
                .volunteerId(volunteerId)
                .userId(SecurityUtils.getUserId())
                .build();
        List<VolunteerSignListVO> signLists = volunteerSignListMapper.getSignList(volunteerSignList);
        //判断是否已经签过到
        for (VolunteerSignListVO signList : signLists) {
            LocalDateTime signTime = signList.getSignTime();
            //如果已经签过到
            if (signTime.isAfter(signBeginTime) && signTime.isBefore(signEndTime)){
                throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_HAS_SIGNED);
            }
        }
        //查询时间币交易
        TimeCoinTrade timeCoinTrade = TimeCoinTrade.builder()
                .volunteerId(volunteerId)
                .getterId(SecurityUtils.getUserId())
                .payerId(volunteer.getPublisherId())
                .delFlag(StatusConstant.DISABLE)
                .build();
        Result<List<TimeCoinTradeVO>> result = remoteTimeCoinService.getTradeByCondition(timeCoinTrade,SecurityConstants.INNER);
        List<TimeCoinTradeVO> timeCoinTrades = result.getData();
        //如果没有创建过时间币交易
        if (timeCoinTrades == null || timeCoinTrades.isEmpty()){
            //创建时间币交易
            timeCoinTrade = TimeCoinTrade.builder()
                    .volunteerId(volunteerId)
                    .getterId(SecurityUtils.getUserId())
                    .getterName(SecurityUtils.getUsername())
                    .payerId(volunteer.getPublisherId())
                    .payerName(volunteer.getCreateBy())
                    .timeCoin(volunteer.getTimeCoin())
                    .build();
            timeCoinTrade.setCreateBy("system");
            timeCoinTrade.setCreateTime(LocalDateTime.now());
            timeCoinTrade.setRemark("签到成功，系统自动创建");
            AjaxResult ajaxResult = remoteTimeCoinService.createTrade(timeCoinTrade, SecurityConstants.INNER);
            if (ajaxResult.isError()){
                return AjaxResult.error(TimeCoinTradeExceptionConstant.TRADE_CREATE_FAILED);
            }
        }
        //查询出席名单
        VolunteerAttendList volunteerAttendList = VolunteerAttendList.builder()
                .volunteerId(volunteerId)
                .userId(SecurityUtils.getUserId())
                .delFlag(StatusConstant.DISABLE)
                .build();
        List<VolunteerAttendListVO> volunteerAttendLists =
                volunteerAttendListMapper.getAttendList(volunteerAttendList);
        //如果没找到出席名单
        if (volunteerAttendLists == null || volunteerAttendLists.isEmpty()){
            //新增出席名单
            volunteerAttendList = VolunteerAttendList.builder()
                    .volunteerId(volunteerId)
                    .userId(SecurityUtils.getUserId())
                    .signTotalTime(1)
                    .createId(999L)
                    .createBy("system")
                    .createTime(LocalDateTime.now())
                    .remark("签到成功，系统自动创建")
                    .build();
            //创建出席名单
            volunteerAttendListMapper.insertAttendList(volunteerAttendList);
        } else {
            volunteerAttendList = volunteerAttendLists.get(0);
            volunteerAttendList.setSignTotalTime(volunteerAttendList.getSignTotalTime() + 1);
            volunteerAttendListMapper.updateAttendList(volunteerAttendList);
        }
        volunteerSignList = VolunteerSignList.builder()
                .volunteerId(volunteerId)
                .userId(SecurityUtils.getUserId())
                .createId(999L)
                .createBy("system")
                .signNum(volunteer.getSignNum())
                .signTime(LocalDateTime.now())
                .remark("志愿者签到成功")
                .build();
        return volunteerSignListMapper.insertSignList(volunteerSignList) > 0 ? AjaxResult.success("签到成功") : AjaxResult.error("签到失败");
    }

    /**
     * 获取志愿者签到记录
     * @param volunteerId
     * @param userId
     * @return
     */
    @Override
    public List<VolunteerSignListVO> getSignListByVolunteerIdAndUserId(Long volunteerId, Long userId) {
        VolunteerSignList volunteerSignList= VolunteerSignList.builder()
                .volunteerId(volunteerId)
                .userId(userId)
                .build();
        return volunteerSignListMapper.getSignList(volunteerSignList);
    }

    /**
     * 检验是否签到
     *
     * @param volunteerId
     * @param userId
     * @return
     */
    @Override
    public Boolean checkSign(Long volunteerId, Long userId) {
        //查询签到名单
        List<VolunteerSignListVO> signLists =
                getSignListByVolunteerIdAndUserId(volunteerId, userId);
        //查询志愿服务
        VolunteerVO volunteer = volunteerMapper.getVolunteerById(volunteerId);
        LocalDateTime signBeginTime = volunteer.getSignBeginTime();
        LocalDateTime signEndTime = volunteer.getSignEndTime();
        //如果未开启过签到
        if (signBeginTime == null || signEndTime == null){
            return false;
        }
        for (VolunteerSignListVO signList : signLists) {
            LocalDateTime signTime = signList.getSignTime();
            if (signTime.isAfter(signBeginTime)
                    && signTime.isBefore(signEndTime)
            ){
                return true;
            }
        }
        return false;
    }
}
